package com.nidu.demo.permission.config;

import com.alibaba.ttl.TransmittableThreadLocal;
import com.nidu.demo.common.enums.DataScopeEnum;
import com.nidu.demo.security.core.LoginUser;
import com.nidu.demo.security.util.SecurityUtils;

import java.util.Set;

/**
 * 数据权限上下文持有者
 */
public class DataPermissionContextHolder {

    /**
     * 当前用户的数据权限范围
     */
    private static final ThreadLocal<DataScopeEnum> DATA_SCOPE = new TransmittableThreadLocal<>();

    /**
     * 当前用户可访问的部门ID集合
     */
    private static final ThreadLocal<Set<Long>> DEPT_IDS = new TransmittableThreadLocal<>();

    /**
     * 是否忽略数据权限
     */
    private static final ThreadLocal<Boolean> IGNORE = new TransmittableThreadLocal<>();

    /**
     * 获取数据权限范围，支持懒加载
     */
    public static DataScopeEnum getDataScope() {
        DataScopeEnum dataScope = DATA_SCOPE.get();
        if (dataScope == null) {
            // 尝试从LoginUser获取
            loadFromLoginUser();
            dataScope = DATA_SCOPE.get();
        }
        return dataScope;
    }

    /**
     * 获取部门ID集合，支持懒加载
     */
    public static Set<Long> getDeptIds() {
        Set<Long> deptIds = DEPT_IDS.get();
        if (deptIds == null) {
            // 尝试从LoginUser获取
            loadFromLoginUser();
            deptIds = DEPT_IDS.get();
        }
        return deptIds;
    }

    /**
     * 从LoginUser懒加载数据权限信息
     */
    private static void loadFromLoginUser() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser != null) {
            DataScopeEnum dataScope = loginUser.getDataScope();
            Set<Long> deptIds = loginUser.getDeptIds();

            if (dataScope != null) {
                DATA_SCOPE.set(dataScope);
                DEPT_IDS.set(deptIds);
            }
        }
    }

    public static void setDataScope(DataScopeEnum dataScope) {
        DATA_SCOPE.set(dataScope);
    }

    public static void setDeptIds(Set<Long> deptIds) {
        DEPT_IDS.set(deptIds);
    }

    public static void setIgnore(Boolean ignore) {
        IGNORE.set(ignore);
    }

    public static boolean isIgnore() {
        return Boolean.TRUE.equals(IGNORE.get());
    }

    public static void clear() {
        DATA_SCOPE.remove();
        DEPT_IDS.remove();
        IGNORE.remove();
    }
}